﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Globalization;
using System.ComponentModel;
using System.Windows.Threading;
using HomeDMSDomain;
using System.Linq;
using System.Data.Linq;
using Microsoft.Win32;
using System.IO;
using System.Drawing;


namespace bind_n_find
{
    /// <summary>
    /// Interaction logic for new_ctrl.xaml
    /// </summary>
    public partial class new_ctrl : UserControl, System.IDisposable
    {
        #region private fields

        private List<image_text_item_template> _im_list = new List<image_text_item_template>();
        private dlg_mode_e _dlg_mode = dlg_mode_e.view_t;
        List<string> _tags_list = new List<string>();
        private Document _doc;
        private BindnFindObjectsDataContext _currentContext;
        private delegate void SimpleDelegate();
        private string_array_search_helper _shelper;

        #endregion //private fields

        #region events
        public static event EventHandler document_collection_changed;
        #endregion //events

        #region public properties
        public dlg_mode_e dlg_mode
        {
            get { return _dlg_mode; }
            set { _dlg_mode = value; }
        }

        #endregion //public properties

        #region construction and initialization

        public new_ctrl()
        {
            InitializeComponent();
            _init();
        }

        private void _init()
        {
            //is fired when image list is updated
            new_edit_dlg.bi_list_updated += new EventHandler(new_edit_dlg_bi_list_updated);
            //is fired when the control is unloaded
            this.Unloaded += new RoutedEventHandler(new_ctrl_Unloaded);
        }

        #endregion //construction and initialization

        #region event handlers
        /// <summary>
        /// Is fired when the control is unloaded
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void new_ctrl_Unloaded(object sender, RoutedEventArgs e)
        {
            image_view1.DataContext = null;
        }
        /// <summary>
        /// Is fired when image list is updated, sets DataContext for ListView
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void new_edit_dlg_bi_list_updated(object sender, EventArgs e)
        {
            if (image_view1.DataContext == null)
            {
                //load current image list from application properties
                _im_list = (List<image_text_item_template>)Application.Current.Properties["BitmapImagesList"];
                if (_im_list != null)
                {
                    //set image view data context 
                    image_view1.DataContext = _im_list;
                }
            }
            _loading_label.Visibility = Visibility.Hidden;
            image_view1.Items.Refresh();


        }

        /// <summary>
        /// Is fired when the control is loaded
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                //get current context
                _currentContext = BindnFindObjectsDataContext.Instance;
                //set current document
                _doc = _currentContext.Documents.Single<Document>(d => d.document_id == Properties.Settings.Default.CurrentDocumentID);

                // fill language combo on the background
                SimpleDelegate del = delegate()
                {
                    language_combo.Items.SortDescriptions.Add(new SortDescription("DisplayName", ListSortDirection.Ascending));
                    language_combo.DataContext = (CultureInfo[])Application.Current.Properties["CultureInfos"];

                };

                this.Dispatcher.BeginInvoke(DispatcherPriority.Background, del);

                _enable_group_box_items((bool)check_box1.IsChecked);
                if (_currentContext != null)
                {
                    //fill tags list
                    search_tags.DataContext = _currentContext.Tags;
                }
                //construct helper for dropdown strings
                _shelper = new string_array_search_helper(_currentContext.Tags);
                _enable_add_tag_button();

                //in the case of new document there is no need to fill the form, so return
                if (_dlg_mode == dlg_mode_e.new_t)
                    return;
                if (_doc == null)
                    return;
                //for existing document, fill the form
                doc_name.Text = _doc.Name;
                doc_description.Text = _doc.Description;
                //load tags list
                foreach (Document_Tag tag in _doc.Document_Tags)
                {
                    _tags_list.Add(tag.Tag.ToString());
                }
                doc_tags.DataContext = _tags_list;

                //load images
                if (_im_list != null)
                {
                    if (_im_list.Count > 0)
                        image_view1.DataContext = _im_list;
                    else
                        image_view1.DataContext = null;
                    if (_im_list.Count == 0)
                    {
                        _loading_label.Visibility = Visibility.Visible;
                    }
                }
                else
                {
                    _loading_label.Visibility = Visibility.Visible;
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        /// <summary>
        /// Is fired when text is changed in 'search' textbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void search_tabs_textbox_TextChanged(object sender, TextChangedEventArgs e)
        {
            try
            {
                _enable_add_tag_button();
                if (_shelper != null)
                {
                    List<string> array = _shelper.update_search(search_tabs_textbox.Text);
                    search_tags.DataContext = array;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        /// <summary>
        /// Is fired when 'Add tag' button is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void add_tag_button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //show 'add new tag' dialog
                add_new_tag_dlg dlg = new add_new_tag_dlg();
                dlg.tag = search_tabs_textbox.Text;
                dlg.Owner = Window.GetWindow(this);
                dlg.ShowInTaskbar = false;
                dlg.ShowDialog();
                if (dlg.DialogResult == true)
                {
                    List<string> array = _shelper.add_string(search_tabs_textbox.Text);
                    search_tags.DataContext = array;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);


            }
        }
        /// <summary>
        /// Is fired when 'delete tag' button is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void delete_tag_button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int count = search_tags.SelectedItems.Count;
                string[] str_array = new string[count];
                for (int i = 0; i < count; ++i)
                {
                    str_array[i] = search_tags.SelectedItems[i].ToString();

                }
                List<string> new_array = _shelper.delete_strings(str_array);
                search_tags.DataContext = new_array;
            }
            catch (Exception ex)
            {
                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        /// <summary>
        /// Is fired when 'left' arrow button is clicked (it means that tag is added to document tag list)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toleft_button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                foreach (object obj in search_tags.SelectedItems)
                {
                    string str = obj.ToString();
                    if (!_tags_list.Contains(str))
                        _tags_list.Add(str);

                }
                doc_tags.Items.Refresh();

            }
            catch (Exception ex)
            {
                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        /// <summary>
        /// Is fired when 'right' arrow button is clicked (it means that tag is removed from document tag list)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toright_button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int count = doc_tags.SelectedItems.Count;
                for (int i = count - 1; i >= 0; --i)
                {
                    object obj = doc_tags.SelectedItems[i];
                    if (obj == null)
                        continue;
                    string str = obj.ToString();
                    if (_tags_list.Contains(str))
                        _tags_list.Remove(str);
                }
                doc_tags.Items.Refresh();
            }
            catch (Exception ex)
            {
                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        /// <summary>
        /// Is fired when 'this document has start/expiration date' checkbox is checked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            _check_box_checked_changed(e);
        }

        /// <summary>
        /// Is fired when 'this document has start/expiration date' checkbox is unchecked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            _check_box_checked_changed(e);
        }

        /// <summary>
        /// Scanner tool button is clicked, show 'acquire from scanner' dialog
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Scanner_Tool_Button_Click(object sender, RoutedEventArgs e)
        {
            acquire_from_scanner_dlg dlg = new acquire_from_scanner_dlg();
            dlg.Owner = Window.GetWindow(this);
            dlg.ShowInTaskbar = false;

            dlg.ShowDialog();
        }

        /// <summary>
        /// 'Save and close' button is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _save_and_close_button_Click(object sender, RoutedEventArgs e)
        {
            if (!_save_document())
                return;

            Window w = Window.GetWindow(this);
            if (w != null) w.Close();

        }

        /// <summary>
        /// 'Import' tool button is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Import_Tool_Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                _import_pic();
            }
            catch (Exception ex)
            {
                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        /// <summary>
        /// 'Remove' tool button is clicked, remove image from image list and reload image list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Remove_Tool_Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int count = image_view1.Items.Count;
                for (int i = count - 1; i >= 0; --i)
                {
                    object obj = image_view1.Items[i];
                    if (obj != null)
                    {
                        ListViewItem item = image_view1.ItemContainerGenerator.ContainerFromItem(obj) as ListViewItem;
                        if (item != null)
                        {
                            if (item.IsSelected)
                            {
                                image_text_item_template it = (image_text_item_template)obj;
                                if (it != null)
                                {
                                    if (_im_list.Contains(it))
                                    {
                                        _im_list.Remove(it);

                                    }
                                }
                            }
                        }
                    }
                }
                _reload_im_list();
            }
            catch (Exception ex)
            {
                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }


        }

        /// <summary>
        /// 'Up' tool button is clicked, move image up
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Up_Tool_Button_Click(object sender, RoutedEventArgs e)
        {
            // TODO: implementation
        }

        /// <summary>
        /// 'Down' tool button is clicked, move image up
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Down_Tool_Button_Click(object sender, RoutedEventArgs e)
        {
            // TODO: implementation
        }



        #endregion //event handlers

        #region private methods

        /// <summary>
        /// Reload image list in ListView control
        /// </summary>
        private void _reload_im_list()
        {
            if (_im_list != null)
            {
                image_view1.DataContext = _im_list;
                image_view1.Items.Refresh();
            }
        }



        /// <summary>
        /// Enable/disable 'add tag' button
        /// </summary>
        private void _enable_add_tag_button()
        {
            try
            {
                if (string.IsNullOrEmpty(search_tabs_textbox.Text))
                    add_tag_button.IsEnabled = false;
                else
                    add_tag_button.IsEnabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Information);
            }

        }

        /// <summary>
        /// Enable/disable date pickers
        /// </summary>
        /// <param name="enable"></param>
        private void _enable_group_box_items(bool enable)
        {
            label7.IsEnabled = enable;
            label8.IsEnabled = enable;
            from_date_picker.IsEnabled = enable;
            to_date_picker.IsEnabled = enable;

        }

        /// <summary>
        /// Enable/disable date pickers according to event args
        /// </summary>
        /// <param name="e"></param>
        private void _check_box_checked_changed(RoutedEventArgs e)
        {
            CheckBox cb = (CheckBox)e.Source;
            if (cb != null)
            {
                _enable_group_box_items((bool)cb.IsChecked);
            }
        }


        /// <summary>
        /// Save document
        /// </summary>
        /// <returns>
        /// 'true' is success otherwise 'false'
        /// </returns>
        private bool _save_document()
        {
            if (string.IsNullOrEmpty(doc_name.Text))
            {
                MessageBox.Show(Window.GetWindow(this), Properties.Resources.DocNameMissingString, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Error);
                doc_name.Focus();
                return false;
            }


            try
            {
                if (_currentContext == null)
                    return false;
          //      _doc = _currentContext.Documents.Single<Document>(d => d.document_id == Properties.Settings.Default.CurrentDocumentID);
                if (_doc == null)
                {
                    _doc = new Document();
                    _doc.EnteredOn = DateTime.Now;
                    _currentContext.Documents.InsertOnSubmit(_doc);
                }


                _doc.Name = doc_name.Text;
                _doc.Description = doc_description.Text;
                if (language_combo.SelectedIndex >= 0)
                {
                    CultureInfo culture = language_combo.SelectedItem as CultureInfo;
                    if (culture != null)
                    {
                        _doc.LCID = culture.LCID;
                    }
                }

                if ((bool)check_box1.IsChecked)
                {
                    _doc.From = from_date_picker.DisplayDate;
                    _doc.To = from_date_picker.DisplayDate;
                }
                else
                {
                    _doc.From = null;
                    _doc.To = null;
                }

                foreach (object obj in image_view1.Items)
                {
                    image_text_item_template item = (image_text_item_template)obj;
                    if (item == null)
                        continue;
                    if (!_pages_contain_id(item.id))
                    {
                        HomeDMSDomain.Page page = new HomeDMSDomain.Page();
                        page.Document = _doc;
                        page.Image = imaging_c.bmp_to_image(item.image);
                        page.Name = item.text;
                        _doc.Pages.Add(page);
                        _currentContext.Pages.InsertOnSubmit(page);
                    }
                }


                int count = _doc.Pages.Count;
                for (int i = count - 1; i >= 0; --i)
                {
                    HomeDMSDomain.Page page = _doc.Pages[i];
                    if (page != null)
                    {
                        if (!_im_list_contains_id(page.page_id))
                        {
                            _doc.Pages.Remove(page);
                            _currentContext.Pages.DeleteOnSubmit(page);
                        }
                    }

                }

                if (_doc.Document_Tags.Count > 0)
                {
                    var q = from dt in _currentContext.Document_Tags where dt.document_id == _doc.document_id select dt;
                    _currentContext.Document_Tags.DeleteAllOnSubmit<Document_Tag>(q);
                    _currentContext.SubmitChanges();
                }

                foreach (string item in doc_tags.Items)
                {
                    Tag tag = new Tag();
                    tag.Name = item;
                    Document_Tag dt = new Document_Tag { Document = _doc, Tag = tag };
                    _currentContext.Document_Tags.InsertOnSubmit(dt);
                }
                _currentContext.SubmitChanges();
                if (document_collection_changed != null)
                {
                    document_collection_changed(this, EventArgs.Empty);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(Window.GetWindow(this), ex.Message, Application.Current.MainWindow.Title, MessageBoxButton.OK, MessageBoxImage.Warning);
                return false;
            }
            return true;
        }

        /// <summary>
        /// Checks if page list contains current page id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private bool _pages_contain_id(int id)
        {
            foreach (HomeDMSDomain.Page page in _doc.Pages)
            {
                if (page.page_id == id)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Checks if image list contains image with current id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private bool _im_list_contains_id(int id)
        {
            foreach (object obj in image_view1.Items)
            {
                image_text_item_template item = (image_text_item_template)obj;
                if (item == null)
                    continue; 
                if (item.id == id || id==0)
                {
                    return true;
                }
            }
            return false;

        }

        /// <summary>
        /// Import image from file/files
        /// </summary>
        private void _import_pic()
        {
            try
            {
                OpenFileDialog dlg = new OpenFileDialog();
                dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
                dlg.Filter = Properties.Resources.Images_File_Dlg_Filter;

                Nullable<bool> result = dlg.ShowDialog(Window.GetWindow(this));
                if (result == true)
                {
                    _import_images(dlg.FileNames);
                }
            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _open_db().";
                throw new Exception(mes);
            }
        }

        /// <summary>
        /// Import multiple images from files
        /// </summary>
        /// <param name="files"></param>
        private void _import_images(string[] files)
        {
            try 
            {
                foreach (string file in files)
                {
                    string ext = System.IO.Path.GetExtension(file).ToLower();
                    if (ext == ".jpg" || ext == ".jpeg" || ext == ".gif" ||
                        ext == ".tif" || ext == ".tiff" || ext == ".bmp" || ext == ".png")
                    {
                        System.Drawing.Image img = null;
                        BitmapImage bimg = null;
                        try
                        {
                            img = Bitmap.FromFile(file);
                         //   JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
                         //   bimg = decoder.Frames[0];

                            // Convert to BitmapImage
                            bimg = imaging_c.image_to_bmp(img);
                          //  bi.StreamSource

                        }
                        catch
                        {
                            continue;
                        }
                        FileInfo fi = new FileInfo(file);
                        _im_list.Add(new image_text_item_template(bimg,fi.Name.Replace(fi.Extension,string.Empty), -1));
                        _reload_im_list();

                       // AddPage(img, fi.Name);
                      //  Repaginate();
                    }
                }
            }
            catch (Exception ex)
            {
                string mes = ex.Message + Environment.NewLine + "Caught in _open_db().";
                throw new Exception(mes);
            }

        }

        #endregion //private methods

        public void Dispose()
        {

        }



    }

    /// <summary>
    /// Template for image element in ListView (includes image, image name, id and check box)
    /// </summary>
    public class image_text_item_template
    {
        private BitmapImage _image;
        public BitmapImage image
        {
            get { return _image; }
        }
        private string _text;
        public string text
        {
            get { return _text; }
        }
        private int _id;
        public int id
        {
            get { return _id; }
        }
        private CheckBox _item_check_box=new CheckBox();
        public CheckBox item_check_box
        {
            get { return _item_check_box; }
        }
        public image_text_item_template(BitmapImage image, string text, int id)
        {
            _image = image;
            _text = text;
            _id = id;
        }
    }
}
